/*
 * Author: 李波(Edwin Lee)
 * Date: 2024-08-20 14:21:12
 * FilePath: /mprpc/src/include/logger.h
 * LastEditTime: 2024-09-03 08:34:04
 * version: 1.0
 * Description: 异步日志系统
 */

#ifndef __LOGGER_H__
#define __LOGGER_H__
#include "lockqueue.hpp"
#include "public.h"
#include <cstdio>
#include <string>
// 日志信息最大值
#define MAX_LOGGER_MSG 512
// 定义宏 LOG_INFO("xxx %d %s", 20, "xxxx")
#define LOG_INFO(logmsgformat, ...) \
    do \
    {  \
        Logger &logger = Logger::getInstance(); \
        char c[MAX_LOGGER_MSG] = {0}; \
        char m[MAX_LOGGER_MSG] = {0}; \
        snprintf(m,MAX_LOGGER_MSG,"%s:%d %s",__FILE__,__LINE__,logmsgformat); \
        sprintf(c, m, ##__VA_ARGS__); \
        logger.info(c); \
    } while(0) \

#define LOG_ERROR(logmsgformat, ...) \
    do \
    {  \
        Logger &logger = Logger::getInstance(); \
        char c[MAX_LOGGER_MSG] = {0}; \
        char m[MAX_LOGGER_MSG] = {0}; \
        snprintf(m,MAX_LOGGER_MSG,"%s:%d %s",__FILE__,__LINE__,logmsgformat); \
        sprintf(c, m, ##__VA_ARGS__); \
        logger.error(c); \
    } while(0) \

#define LOG_DEBUG(logmsgformat, ...) \
    do \
    {  \
        Logger &logger = Logger::getInstance(); \
        char c[MAX_LOGGER_MSG] = {0}; \
        char m[MAX_LOGGER_MSG] = {0}; \
        snprintf(m,MAX_LOGGER_MSG,"%s:%d %s",__FILE__,__LINE__,logmsgformat); \
        sprintf(c, m, ##__VA_ARGS__); \
        logger.debug(c); \
    } while(0) \

#define LOG_FATAL(logmsgformat, ...) \
    do \
    {  \
        Logger &logger = Logger::getInstance(); \
        char c[MAX_LOGGER_MSG] = {0}; \
        char m[MAX_LOGGER_MSG] = {0}; \
        snprintf(m,MAX_LOGGER_MSG,"%s:%d %s",__FILE__,__LINE__,logmsgformat); \
        sprintf(c, m, ##__VA_ARGS__); \
        logger.fatal(c); \
    } while(0) \

#define LOG_LOG(logmsgformat, ...) \
    do \
    {  \
        Logger &logger = Logger::getInstance(); \
        char c[MAX_LOGGER_MSG] = {0}; \
        snprintf(c, MAX_LOGGER_MSG, logmsgformat, ##__VA_ARGS__); \
        logger.log(c); \
    } while(0) \
    
// Mprpc框架提供的日志系统
class Logger
{
public:
    ~Logger();
    //description: 获取日志单例
    //Date: 2024-08-21 10:42:34
    static Logger& getInstance();
    //description: 设置写入日志文件是否采用缓存（默认是true）
    //param cache: true：采用缓存 false：不采用缓存执行fflush()
    //Date: 2024-08-23 05:38:44
    inline void setCache(bool cache) noexcept {cache_ = cache;}
    //description: 设置是否备份文件，默认备份true
    //param backup: true:备份文件 false:不备份文件，日志文件可能会过大
    //Date: 2024-08-23 05:42:26
    inline void setBackup(bool backup) noexcept {backup_ = backup;}
    //description: 设置为debug模式,默认为非debug模式（false)，
    //非debug模式下Logger::debug（）不输出信息
    //param debug:true：debug模式 false：非debug模式
    //Date: 2024-08-23 05:44:43
	inline void setDebug(bool debug) noexcept { debug_ = debug; }
    //description: 设置日志大小的最大值
    //param size:size>=10,如果size<10会自动设置为10
    //Date: 2024-08-23 05:47:18
	void setMaxLogFileSize(size_t size) noexcept;

	//info:普通日志信息
	bool info(const char* fmt,...);
	//fatal：致命信息
	bool fatal(const char* fmt,...);
	//debug：测试信息，如debug_==false(默认)输出为空，需要先调用setDebug()
	bool debug(const char* fmt,...);
	//error：普通错误信息
	bool error(const char* fmt,...);
	//输出不带标志和日期的信息（输出什么就写什么不添加其他内容）
	bool log(const char* fmt, ...);

private:
    LockQueue<std::string> lckQue_;         //日志缓冲队列
    std::string dir_;                       //日志的路径默认当前目录下logger文件夹
	std::string filename_;					//日志文件路径
	FILE* logfile_;							//打开的日志文件句柄
	bool cache_;							//写入日志时，是否启用操作系统的缓冲机制
	bool backup_;							//是否自动备份文件，日志文件大小超过maxLogFileSize时自动备份
	bool debug_;							//是否debug模式，影响logdebug()函数是否会输出debug信息
	size_t maxLogFileSize_;					//日志文件触发备份的阈值（单位M）,小于10的话会设置为10
    LTime time_;                            //时间操作类

    //description: 构造函数
    //param dir:日志的路径默认当前目录下logger文件夹,末尾必须带'/'
    //Date: 2024-08-22 13:48:46
    Logger(std::string dir="./logger/");
    Logger(const Logger&) = delete;
    Logger(Logger&&) = delete;
    //description: 备份日志文件
    //return {bool}:备份成功返回true，失败返回false
    //Date: 2024-08-23 05:49:27
	bool backupLogFile();
};

#endif
